home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / plug-ins / common / tiff.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-05-16  |  47.9 KB  |  1,690 lines

  1. /* tiff loading and saving for the GIMP
  2.  *  -Peter Mattis
  3.  * The TIFF loading code has been completely revamped by Nick Lamb
  4.  * njl195@zepler.org.uk -- 18 May 1998
  5.  * And it now gains support for tiles (and doubtless a zillion bugs)
  6.  * njl195@zepler.org.uk -- 12 June 1999
  7.  * LZW patent fuss continues :(
  8.  * njl195@zepler.org.uk -- 20 April 2000
  9.  * The code for this filter is based on "tifftopnm" and "pnmtotiff",
  10.  *  2 programs that are a part of the netpbm package.
  11.  * khk@khk.net -- 13 May 2000
  12.  * Added support for ICCPROFILE tiff tag. If this tag is present in a 
  13.  * TIFF file, then a parasite is created and vice versa.
  14.  * peter@kirchgessner.net -- 29 Oct 2002
  15.  * Progress bar only when run interactive
  16.  */
  17.  
  18. /*
  19. ** tifftopnm.c - converts a Tagged Image File to a portable anymap
  20. **
  21. ** Derived by Jef Poskanzer from tif2ras.c, which is:
  22. **
  23. ** Copyright (c) 1990 by Sun Microsystems, Inc.
  24. **
  25. ** Author: Patrick J. Naughton
  26. ** naughton@wind.sun.com
  27. **
  28. ** This file is provided AS IS with no warranties of any kind.  The author
  29. ** shall have no liability with respect to the infringement of copyrights,
  30. ** trade secrets or any patents by this file or any part thereof.  In no
  31. ** event will the author be liable for any lost revenue or profits or
  32. ** other special, indirect and consequential damages.
  33. */
  34.  
  35. #include "config.h"
  36.  
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <tiffio.h>
  40.  
  41. #include <libgimp/gimp.h>
  42. #include <libgimp/gimpui.h>
  43.  
  44. #include "libgimp/stdplugins-intl.h"
  45.  
  46.  
  47. typedef struct
  48. {
  49.   gint  compression;
  50.   gint  fillorder;
  51. } TiffSaveVals;
  52.  
  53. typedef struct
  54. {
  55.   gint  run;
  56. } TiffSaveInterface;
  57.  
  58. typedef struct
  59. {
  60.   gint32     ID;
  61.   GimpDrawable *drawable;
  62.   GimpPixelRgn  pixel_rgn;
  63.   guchar    *pixels;
  64.   guchar    *pixel;
  65. } channel_data;
  66.  
  67. /* Declare some local functions.
  68.  */
  69. static void   query   (void);
  70. static void   run     (gchar   *name,
  71.                gint     nparams,
  72.                GimpParam  *param,
  73.                gint    *nreturn_vals,
  74.                GimpParam **return_vals);
  75.  
  76. static gint32 load_image    (gchar        *filename);
  77.  
  78. static void   load_rgba     (TIFF         *tif,
  79.                  channel_data *channel);
  80. static void   load_lines    (TIFF         *tif,
  81.                  channel_data *channel,
  82.                  gushort       bps,
  83.                  gushort       photomet,
  84.                  gint          alpha,
  85.                  gint          extra);
  86. static void   load_tiles    (TIFF         *tif,
  87.                  channel_data *channel,
  88.                  gushort       bps,
  89.                  gushort       photomet,
  90.                  gint          alpha,
  91.                  gint          extra);
  92.  
  93. static void   read_separate (guchar       *source,
  94.                  channel_data *channel,
  95.                              gushort       bps,
  96.                  gushort       photomet,
  97.                              gint          startcol,
  98.                  gint          startrow,
  99.                  gint          rows,
  100.                  gint          cols,
  101.                              gint          alpha,
  102.                  gint          extra,
  103.                  gint          sample);
  104. static void   read_16bit    (guchar       *source,
  105.                  channel_data *channel,
  106.                  gushort       photomet,
  107.                  gint          startcol,
  108.                  gint          startrow,
  109.                  gint          rows,
  110.                  gint          cols,
  111.                  gint          alpha,
  112.                  gint          extra,
  113.                  gint          align);
  114. static void   read_8bit     (guchar       *source,
  115.                  channel_data *channel,
  116.                  gushort       photomet,
  117.                  gint          startcol,
  118.                  gint          startrow,
  119.                  gint          rows,
  120.                  gint          cols,
  121.                  gint          alpha,
  122.                  gint          extra,
  123.                  gint          align);
  124. static void   read_default  (guchar       *source,
  125.                  channel_data *channel,
  126.                  gushort       bps,
  127.                  gushort       photomet,
  128.                  gint          startcol,
  129.                  gint          startrow,
  130.                  gint          rows,
  131.                  gint          cols,
  132.                  gint          alpha,
  133.                  gint          extra,
  134.                  gint          align);
  135.  
  136. static gint   save_image             (gchar     *filename,
  137.                       gint32     image,
  138.                       gint32     drawable,
  139.                       gint32     orig_image);
  140.  
  141. static gint   save_dialog            (void);
  142.  
  143. static void   save_ok_callback       (GtkWidget *widget,
  144.                       gpointer   data);
  145. static void   comment_entry_callback (GtkWidget *widget,
  146.                       gpointer   data);
  147.  
  148. GimpPlugInInfo PLUG_IN_INFO =
  149. {
  150.   NULL,  /* init_proc  */
  151.   NULL,  /* quit_proc  */
  152.   query, /* query_proc */
  153.   run,   /* run_proc   */
  154. };
  155.  
  156. static TiffSaveVals tsvals =
  157. {
  158.   COMPRESSION_NONE,    /*  compression  */
  159. };
  160.  
  161. static TiffSaveInterface tsint =
  162. {
  163.   FALSE               /*  run  */
  164. };
  165.  
  166. static char *image_comment= NULL;
  167.  
  168. static GimpRunModeType run_mode = GIMP_RUN_INTERACTIVE;
  169.  
  170. MAIN ()
  171.  
  172. static void
  173. query (void)
  174. {
  175.   static GimpParamDef load_args[] =
  176.   {
  177.     { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
  178.     { GIMP_PDB_STRING, "filename", "The name of the file to load" },
  179.     { GIMP_PDB_STRING, "raw_filename", "The name of the file to load" }
  180.   };
  181.   static GimpParamDef load_return_vals[] =
  182.   {
  183.     { GIMP_PDB_IMAGE, "image", "Output image" }
  184.   };
  185.   static gint nload_args = sizeof (load_args) / sizeof (load_args[0]);
  186.   static gint nload_return_vals = (sizeof (load_return_vals) /
  187.                    sizeof (load_return_vals[0]));
  188.  
  189.   static GimpParamDef save_args[] =
  190.   {
  191.     { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
  192.     { GIMP_PDB_IMAGE, "image", "Input image" },
  193.     { GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" },
  194.     { GIMP_PDB_STRING, "filename", "The name of the file to save the image in" },
  195.     { GIMP_PDB_STRING, "raw_filename", "The name of the file to save the image in" },
  196.     { GIMP_PDB_INT32, "compression", "Compression type: { NONE (0), LZW (1), PACKBITS (2), DEFLATE (3), JPEG (4)" }
  197.   };
  198.   static gint nsave_args = sizeof (save_args) / sizeof (save_args[0]);
  199.  
  200.   gimp_install_procedure ("file_tiff_load",
  201.                           "loads files of the tiff file format",
  202.                           "FIXME: write help for tiff_load",
  203.                           "Spencer Kimball, Peter Mattis & Nick Lamb",
  204.                           "Nick Lamb <njl195@zepler.org.uk>",
  205.                           "1995-1996,1998-2000",
  206.                           "<Load>/Tiff",
  207.               NULL,
  208.                           GIMP_PLUGIN,
  209.                           nload_args, nload_return_vals,
  210.                           load_args, load_return_vals);
  211.  
  212.   gimp_install_procedure ("file_tiff_save",
  213.                           "saves files in the tiff file format",
  214.                           "Saves files in the Tagged Image File Format.  "
  215.               "The value for the saved comment is taken "
  216.               "from the 'gimp-comment' parasite.",
  217.                           "Spencer Kimball & Peter Mattis",
  218.                           "Spencer Kimball & Peter Mattis",
  219.                           "1995-1996,2000",
  220.                           "<Save>/Tiff",
  221.               "RGB*, GRAY*, INDEXED",
  222.                           GIMP_PLUGIN,
  223.                           nsave_args, 0,
  224.                           save_args, NULL);
  225.  
  226.   gimp_register_magic_load_handler ("file_tiff_load",
  227.                     "tif,tiff",
  228.                     "",
  229.                     "0,string,II*\\0,0,string,MM\\0*");
  230.   gimp_register_save_handler       ("file_tiff_save",
  231.                     "tif,tiff",
  232.                     "");
  233. }
  234.  
  235. static void
  236. run (gchar   *name,
  237.      gint     nparams,
  238.      GimpParam  *param,
  239.      gint    *nreturn_vals,
  240.      GimpParam **return_vals)
  241. {
  242.   static GimpParam values[2];
  243.   GimpPDBStatusType   status = GIMP_PDB_SUCCESS;
  244. #ifdef GIMP_HAVE_PARASITES
  245.   GimpParasite *parasite;
  246. #endif /* GIMP_HAVE_PARASITES */
  247.   gint32        image;
  248.   gint32        drawable;
  249.   gint32        orig_image;
  250.   GimpExportReturnType export = GIMP_EXPORT_CANCEL;
  251.  
  252.   run_mode = param[0].data.d_int32;
  253.  
  254.   *nreturn_vals = 1;
  255.   *return_vals  = values;
  256.   values[0].type          = GIMP_PDB_STATUS;
  257.   values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
  258.  
  259.   if (strcmp (name, "file_tiff_load") == 0)
  260.     {
  261.       INIT_I18N_UI();
  262.       image = load_image (param[1].data.d_string);
  263.  
  264.       if (image != -1)
  265.     {
  266.       *nreturn_vals = 2;
  267.       values[1].type         = GIMP_PDB_IMAGE;
  268.       values[1].data.d_image = image;
  269.     }
  270.       else
  271.     {
  272.       status = GIMP_PDB_EXECUTION_ERROR;
  273.     }
  274.     }
  275.   else if (strcmp (name, "file_tiff_save") == 0)
  276.     {
  277.       image = orig_image = param[1].data.d_int32;
  278.       drawable = param[2].data.d_int32;
  279.  
  280.       /* Do this right this time, if POSSIBLE query for parasites, otherwise
  281.      or if there isn't one, set the comment to an empty string */
  282.  
  283.       /*  eventually export the image */ 
  284.       switch (run_mode)
  285.     {
  286.     case GIMP_RUN_INTERACTIVE:
  287.     case GIMP_RUN_WITH_LAST_VALS:
  288.       INIT_I18N_UI();
  289.       gimp_ui_init ("tiff", FALSE);
  290.       export = gimp_export_image (&image, &drawable, "TIFF", 
  291.                       (GIMP_EXPORT_CAN_HANDLE_RGB |
  292.                        GIMP_EXPORT_CAN_HANDLE_GRAY |
  293.                        GIMP_EXPORT_CAN_HANDLE_INDEXED | 
  294.                        GIMP_EXPORT_CAN_HANDLE_ALPHA ));
  295.       if (export == GIMP_EXPORT_CANCEL)
  296.         {
  297.           values[0].data.d_status = GIMP_PDB_CANCEL;
  298.           return;
  299.         }
  300.       break;
  301.     default:
  302.       break;
  303.     }
  304.  
  305. #ifdef GIMP_HAVE_PARASITES
  306.       parasite = gimp_image_parasite_find (orig_image, "gimp-comment");
  307.       if (parasite)
  308.         image_comment = g_strdup (parasite->data);
  309.       gimp_parasite_free (parasite);
  310. #endif /* GIMP_HAVE_PARASITES */
  311.  
  312.       switch (run_mode)
  313.     {
  314.     case GIMP_RUN_INTERACTIVE:
  315.       /*  Possibly retrieve data  */
  316.       gimp_get_data ("file_tiff_save", &tsvals);
  317.  
  318. #ifdef GIMP_HAVE_PARASITES
  319.       parasite = gimp_image_parasite_find (orig_image, "tiff-save-options");
  320.       if (parasite)
  321.         {
  322.           tsvals.compression =
  323.         ((TiffSaveVals *) parasite->data)->compression;
  324.         }
  325.       gimp_parasite_free (parasite);
  326. #endif /* GIMP_HAVE_PARASITES */
  327.  
  328.       /*  First acquire information with a dialog  */
  329.       if (! save_dialog ())
  330.         status = GIMP_PDB_CANCEL;
  331.       break;
  332.  
  333.     case GIMP_RUN_NONINTERACTIVE:
  334.       INIT_I18N();
  335.       /*  Make sure all the arguments are there!  */
  336.       if (nparams != 6)
  337.         {
  338.           status = GIMP_PDB_CALLING_ERROR;
  339.         }
  340.       else
  341.         {
  342.           switch (param[5].data.d_int32)
  343.         {
  344.         case 0: tsvals.compression = COMPRESSION_NONE;     break;
  345.         case 1: tsvals.compression = COMPRESSION_LZW;      break;
  346.         case 2: tsvals.compression = COMPRESSION_PACKBITS; break;
  347.         case 3: tsvals.compression = COMPRESSION_DEFLATE;  break;
  348.         case 4: tsvals.compression = COMPRESSION_JPEG;  break;
  349.         default: status = GIMP_PDB_CALLING_ERROR; break;
  350.         }
  351.         }
  352.       break;
  353.  
  354.     case GIMP_RUN_WITH_LAST_VALS:
  355.       /*  Possibly retrieve data  */
  356.       gimp_get_data ("file_tiff_save", &tsvals);
  357.  
  358. #ifdef GIMP_HAVE_PARASITES
  359.       parasite = gimp_image_parasite_find (orig_image, "tiff-save-options");
  360.       if (parasite)
  361.         {
  362.           tsvals.compression =
  363.         ((TiffSaveVals *) parasite->data)->compression;
  364.         }
  365.       gimp_parasite_free (parasite);
  366. #endif /* GIMP_HAVE_PARASITES */
  367.       break;
  368.  
  369.     default:
  370.       break;
  371.     }
  372.  
  373.       if (status == GIMP_PDB_SUCCESS)
  374.     {
  375.       if (save_image (param[3].data.d_string, image, drawable, orig_image))
  376.         {
  377.           /*  Store mvals data  */
  378.           gimp_set_data ("file_tiff_save", &tsvals, sizeof (TiffSaveVals));
  379.         }
  380.       else
  381.         {
  382.           status = GIMP_PDB_EXECUTION_ERROR;
  383.         }
  384.     }
  385.  
  386.       if (export == GIMP_EXPORT_EXPORT)
  387.     gimp_image_delete (image);
  388.     }
  389.   else
  390.     {
  391.       status = GIMP_PDB_CALLING_ERROR;
  392.     }
  393.  
  394.   values[0].data.d_status = status;
  395. }
  396.  
  397. static void
  398. tiff_warning(const char* module, const char* fmt, va_list ap)
  399. {
  400.   g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
  401. }
  402.   
  403. static void
  404. tiff_error(const char* module, const char* fmt, va_list ap)
  405. {
  406.   g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, ap);
  407. }
  408.   
  409. static gint32
  410. load_image (gchar *filename) 
  411. {
  412.   TIFF    *tif;
  413.   gushort  bps, spp, photomet;
  414.   gint     cols, rows, alpha;
  415.   gint     image, image_type = GIMP_RGB;
  416.   gint     layer, layer_type = GIMP_RGB_IMAGE;
  417.   gushort  extra, *extra_types;
  418.   channel_data *channel= NULL;
  419.  
  420.   gushort *redmap, *greenmap, *bluemap;
  421.   guchar   colors[3]= {0, 0, 0};
  422.   guchar   cmap[768];
  423.  
  424.   gint   i, j, worst_case = 0;
  425.   gchar *name;
  426.  
  427.   TiffSaveVals save_vals;
  428. #ifdef GIMP_HAVE_PARASITES
  429.   GimpParasite *parasite;
  430. #endif /* GIMP_HAVE_PARASITES */
  431.   guint16 tmp;
  432. #ifdef TIFFTAG_ICCPROFILE
  433.   uint32 profile_size;
  434.   guchar *icc_profile;
  435. #endif
  436.  
  437.   TIFFSetWarningHandler (tiff_warning);
  438.   TIFFSetErrorHandler (tiff_error);
  439.  
  440.   tif = TIFFOpen (filename, "r");
  441.   if (!tif) {
  442.     g_message ("TIFF Can't open %s\n", filename);
  443.     gimp_quit ();
  444.   }
  445.  
  446.   if (run_mode == GIMP_RUN_INTERACTIVE) {
  447.     name = g_strdup_printf( _("Loading %s:"), filename);
  448.     gimp_progress_init (name);
  449.     g_free (name);
  450.   }
  451.  
  452.   TIFFGetFieldDefaulted (tif, TIFFTAG_BITSPERSAMPLE, &bps);
  453.  
  454.   if (bps > 8 && bps != 16) {
  455.     worst_case = 1; /* Wrong sample width => RGBA */
  456.   }
  457.  
  458.   TIFFGetFieldDefaulted (tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
  459.  
  460.   if (!TIFFGetField (tif, TIFFTAG_EXTRASAMPLES, &extra, &extra_types))
  461.     extra = 0;
  462.  
  463.   if (!TIFFGetField (tif, TIFFTAG_IMAGEWIDTH, &cols)) {
  464.     g_message ("TIFF Can't get image width\n");
  465.     gimp_quit ();
  466.   }
  467.  
  468.   if (!TIFFGetField (tif, TIFFTAG_IMAGELENGTH, &rows)) {
  469.     g_message ("TIFF Can't get image length\n");
  470.     gimp_quit ();
  471.   }
  472.  
  473.   if (!TIFFGetField (tif, TIFFTAG_PHOTOMETRIC, &photomet)) {
  474.     g_message("TIFF Can't get photometric\nAssuming min-is-black\n");
  475.     /* old AppleScan software misses out the photometric tag (and
  476.      * incidentally assumes min-is-white, but xv assumes min-is-black,
  477.      * so we follow xv's lead.  It's not much hardship to invert the
  478.      * image later). */
  479.     photomet = PHOTOMETRIC_MINISBLACK;
  480.   }
  481.  
  482.   /* test if the extrasample represents an associated alpha channel... */
  483.   if (extra > 0 && (extra_types[0] == EXTRASAMPLE_ASSOCALPHA)) {
  484.     alpha = 1;
  485.     --extra;
  486.   } else {
  487.     alpha = 0;
  488.   }
  489.  
  490.   if (photomet == PHOTOMETRIC_RGB && spp > 3 + extra) {
  491.     alpha= 1;
  492.     extra= spp - 4; 
  493.   } else if (photomet != PHOTOMETRIC_RGB && spp > 1 + extra) {
  494.     alpha= 1;
  495.     extra= spp - 2;
  496.   }
  497.  
  498.   switch (photomet) {
  499.     case PHOTOMETRIC_MINISBLACK:
  500.     case PHOTOMETRIC_MINISWHITE:
  501.       image_type = GIMP_GRAY;
  502.       layer_type = (alpha) ? GIMP_GRAYA_IMAGE : GIMP_GRAY_IMAGE;
  503.       break;
  504.  
  505.     case PHOTOMETRIC_RGB:
  506.       image_type = GIMP_RGB;
  507.       layer_type = (alpha) ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE;
  508.       break;
  509.  
  510.     case PHOTOMETRIC_PALETTE:
  511.       image_type = GIMP_INDEXED;
  512.       layer_type = (alpha) ? GIMP_INDEXEDA_IMAGE : GIMP_INDEXED_IMAGE;
  513.       break;
  514.  
  515.     default:
  516.       worst_case = 1;
  517.   }
  518.  
  519.   if (worst_case) {
  520.     image_type = GIMP_RGB;
  521.     layer_type = GIMP_RGBA_IMAGE;
  522.   }
  523.  
  524.   if ((image = gimp_image_new (cols, rows, image_type)) == -1) {
  525.     g_message("TIFF Can't create a new image\n");
  526.     gimp_quit ();
  527.   }
  528.   gimp_image_set_filename (image, filename);
  529.  
  530.   /* attach a parasite containing an ICC profile - if found in the TIFF file */
  531.  
  532. #ifdef TIFFTAG_ICCPROFILE
  533.     /* If TIFFTAG_ICCPROFILE is defined we are dealing with a libtiff version 
  534.          * that can handle ICC profiles. Otherwise just ignore this section. */
  535.   if (TIFFGetField (tif, TIFFTAG_ICCPROFILE, &profile_size, &icc_profile)) {
  536. #ifdef GIMP_HAVE_PARASITES
  537.     parasite = gimp_parasite_new("icc-profile", 0,
  538.                 profile_size, icc_profile);
  539.     gimp_image_parasite_attach(image, parasite);
  540.     gimp_parasite_free(parasite);
  541. #endif
  542.   }    
  543. #endif
  544.  
  545.   /* attach a parasite containing the compression */
  546.   if (!TIFFGetField (tif, TIFFTAG_COMPRESSION, &tmp))
  547.     save_vals.compression = COMPRESSION_NONE;
  548.   else
  549.     save_vals.compression = tmp;
  550. #ifdef GIMP_HAVE_PARASITES
  551.   parasite = gimp_parasite_new ("tiff-save-options", 0,
  552.                 sizeof (save_vals), &save_vals);
  553.   gimp_image_parasite_attach (image, parasite);
  554.   gimp_parasite_free (parasite);
  555. #endif /* GIMP_HAVE_PARASITES */
  556.  
  557.  
  558.   /* Attach a parasite containing the image description.  Pretend to
  559.    * be a gimp comment so other plugins will use this description as
  560.    * an image comment where appropriate. */
  561. #ifdef GIMP_HAVE_PARASITES
  562.   {
  563.     char *img_desc;
  564.  
  565.     if (TIFFGetField (tif, TIFFTAG_IMAGEDESCRIPTION, &img_desc))
  566.     {
  567.       int len;
  568.  
  569.       len = strlen(img_desc) + 1;
  570.       len = MIN(len, 241);
  571.       img_desc[len-1] = '\000';
  572.  
  573.       parasite = gimp_parasite_new ("gimp-comment",
  574.                     GIMP_PARASITE_PERSISTENT,
  575.                     len, img_desc);
  576.       gimp_image_parasite_attach (image, parasite);
  577.       gimp_parasite_free (parasite);
  578.     }
  579.   }
  580. #endif /* GIMP_HAVE_PARASITES */
  581.  
  582.   /* any resolution info in the file? */
  583. #ifdef GIMP_HAVE_RESOLUTION_INFO
  584.   {
  585.     gfloat   xres = 72.0, yres = 72.0;
  586.     gushort  read_unit;
  587.     GimpUnit unit = GIMP_UNIT_PIXEL; /* invalid unit */
  588.  
  589.     if (TIFFGetField (tif, TIFFTAG_XRESOLUTION, &xres)) {
  590.       if (TIFFGetField (tif, TIFFTAG_YRESOLUTION, &yres)) {
  591.  
  592.     if (TIFFGetFieldDefaulted (tif, TIFFTAG_RESOLUTIONUNIT, &read_unit)) 
  593.       {
  594.         switch (read_unit) 
  595.           {
  596.           case RESUNIT_NONE:
  597.         /* ImageMagick writes files with this silly resunit */
  598.         g_message ("TIFF warning: resolution units meaningless\n");
  599.         break;
  600.         
  601.           case RESUNIT_INCH:
  602.         unit = GIMP_UNIT_INCH;
  603.         break;
  604.         
  605.           case RESUNIT_CENTIMETER:
  606.         xres *= 2.54;
  607.         yres *= 2.54;
  608.         unit = GIMP_UNIT_MM; /* as this is our default metric unit */
  609.         break;
  610.         
  611.           default:
  612.         g_message ("TIFF file error: unknown resolution unit type %d, "
  613.                "assuming dpi\n", read_unit);
  614.         break;
  615.           }
  616.       } 
  617.     else 
  618.       { /* no res unit tag */
  619.         /* old AppleScan software produces these */
  620.         g_message ("TIFF warning: resolution specified without\n"
  621.                "any units tag, assuming dpi\n");
  622.       }
  623.       }
  624.       else 
  625.     { /* xres but no yres */
  626.       g_message("TIFF warning: no y resolution info, assuming same as x\n");
  627.       yres = xres;
  628.     }
  629.  
  630.       /* now set the new image's resolution info */
  631.  
  632.       /* If it is invalid, instead of forcing 72dpi, do not set the resolution 
  633.      at all. Gimp will then use the default set by the user */
  634.       if (read_unit != RESUNIT_NONE)
  635.     {
  636.       gimp_image_set_resolution (image, xres, yres);
  637.       if (unit != GIMP_UNIT_PIXEL)
  638.         gimp_image_set_unit (image, unit);
  639.     }
  640.     }
  641.  
  642.     /* no x res tag => we assume we have no resolution info, so we
  643.      * don't care.  Older versions of this plugin used to write files
  644.      * with no resolution tags at all. */
  645.  
  646.     /* TODO: haven't caught the case where yres tag is present, but
  647.        not xres.  This is left as an exercise for the reader - they
  648.        should feel free to shoot the author of the broken program
  649.        that produced the damaged TIFF file in the first place. */
  650.   }
  651. #endif /* GIMP_HAVE_RESOLUTION_INFO */
  652.  
  653.  
  654.   /* Install colormap for INDEXED images only */
  655.   if (image_type == GIMP_INDEXED) 
  656.     {
  657.       if (!TIFFGetField (tif, TIFFTAG_COLORMAP, &redmap, &greenmap, &bluemap)) 
  658.     {
  659.       g_message ("TIFF Can't get colormaps\n");
  660.       gimp_quit ();
  661.     }
  662.  
  663.       for (i = 0, j = 0; i < (1 << bps); i++) 
  664.     {
  665.       cmap[j++] = redmap[i] >> 8;
  666.       cmap[j++] = greenmap[i] >> 8;
  667.       cmap[j++] = bluemap[i] >> 8;
  668.     }
  669.       gimp_image_set_cmap (image, cmap, (1 << bps));
  670.     }
  671.  
  672.   /* Allocate channel_data for all channels, even the background layer */
  673.   channel = g_new (channel_data, extra + 1);
  674.   layer = gimp_layer_new (image, _("Background"), cols, rows, layer_type,
  675.                  100, GIMP_NORMAL_MODE);
  676.   channel[0].ID= layer;
  677.   gimp_image_add_layer (image, layer, 0);
  678.   channel[0].drawable= gimp_drawable_get(layer);
  679.  
  680.   if (extra > 0 && !worst_case) {
  681.     /* Add alpha channels as appropriate */
  682.     for (i= 1; i <= extra; ++i) {
  683.       channel[i].ID= gimp_channel_new(image, _("TIFF Channel"), cols, rows,
  684.                                                             100.0, colors);
  685.       gimp_image_add_channel(image, channel[i].ID, 0);
  686.       channel[i].drawable= gimp_drawable_get (channel[i].ID);
  687.     }
  688.   }
  689.  
  690.   if (worst_case) {
  691.     load_rgba (tif, channel);
  692.   } else if (TIFFIsTiled(tif)) {
  693.     load_tiles (tif, channel, bps, photomet, alpha, extra);
  694.   } else { /* Load scanlines in tile_height chunks */
  695.     load_lines (tif, channel, bps, photomet, alpha, extra);
  696.   }
  697.  
  698.   for (i= 0; !worst_case && i < extra; ++i) {
  699.     gimp_drawable_flush (channel[i].drawable);
  700.     gimp_drawable_detach (channel[i].drawable);
  701.   }
  702.  
  703.   return image;
  704. }
  705.  
  706. static void
  707. load_rgba (TIFF *tif, channel_data *channel)
  708. {
  709.   uint32 imageWidth, imageLength;
  710.   uint32 row;
  711.   uint32 *buffer;
  712.  
  713.   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
  714.   TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
  715.   gimp_pixel_rgn_init (&(channel[0].pixel_rgn), channel[0].drawable,
  716.                           0, 0, imageWidth, imageLength, TRUE, FALSE);
  717.   buffer = g_new(uint32, imageWidth * imageLength);
  718.   channel[0].pixels = (guchar*) buffer;
  719.   if (buffer == NULL) {
  720.     g_message("TIFF Unable to allocate temporary buffer\n");
  721.   }
  722.   if (!TIFFReadRGBAImage(tif, imageWidth, imageLength, buffer, 0))
  723.     g_message("TIFF Unsupported layout, no RGBA loader\n");
  724.  
  725.   for (row = 0; row < imageLength; ++row) {
  726.     gimp_pixel_rgn_set_rect(&(channel[0].pixel_rgn),
  727.                               channel[0].pixels + row * imageWidth * 4,
  728.                               0, imageLength -row -1, imageWidth, 1);
  729.     if (run_mode == GIMP_RUN_INTERACTIVE)
  730.       gimp_progress_update ((double) row / (double) imageLength);
  731.   }
  732. }
  733.  
  734. static void
  735. load_tiles (TIFF *tif, channel_data *channel,
  736.        unsigned short bps, unsigned short photomet,
  737.        int alpha, int extra)
  738. {
  739.   uint16 planar= PLANARCONFIG_CONTIG;
  740.   uint32 imageWidth, imageLength;
  741.   uint32 tileWidth, tileLength;
  742.   uint32 x, y, rows, cols;
  743.   guchar *buffer;
  744.   double progress= 0.0, one_row;
  745.   int i;
  746.  
  747.   TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar);
  748.   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
  749.   TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
  750.   TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth);
  751.   TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileLength);
  752.   one_row = (double) tileLength / (double) imageLength;
  753.   buffer = g_malloc(TIFFTileSize(tif));
  754.  
  755.   for (i= 0; i <= extra; ++i) {
  756.     channel[i].pixels= g_new(guchar, tileWidth * tileLength *
  757.                                       channel[i].drawable->bpp);
  758.   }
  759.  
  760.   for (y = 0; y < imageLength; y += tileLength) {
  761.     for (x = 0; x < imageWidth; x += tileWidth) {
  762.       if (run_mode == GIMP_RUN_INTERACTIVE)
  763.         gimp_progress_update (progress + one_row *
  764.                               ( (double) x / (double) imageWidth));
  765.       TIFFReadTile(tif, buffer, x, y, 0, 0);
  766.       cols= MIN(imageWidth - x, tileWidth);
  767.       rows= MIN(imageLength - y, tileLength);
  768.       if (bps == 16) {
  769.         g_message("WARNING: The GIMP does not support 16 bits per channel. Truncating data to 8 bits per channel.");
  770.         read_16bit(buffer, channel, photomet, y, x, rows, cols, alpha,
  771.                    extra, tileWidth - cols);
  772.       } else if (bps == 8) {
  773.         read_8bit(buffer, channel, photomet, y, x, rows, cols, alpha,
  774.                   extra, tileWidth - cols);
  775.       } else {
  776.         read_default(buffer, channel, bps, photomet, y, x, rows, cols,
  777.                      alpha, extra, tileWidth - cols);
  778.       }
  779.     }
  780.     progress+= one_row;
  781.   }
  782.   for (i= 0; i <= extra; ++i) {
  783.     g_free(channel[i].pixels);
  784.   }
  785.   g_free(buffer);
  786. }
  787.  
  788. static void
  789. load_lines (TIFF *tif, channel_data *channel,
  790.         unsigned short bps, unsigned short photomet,
  791.         int alpha, int extra)
  792. {
  793.   uint16 planar= PLANARCONFIG_CONTIG;
  794.   uint32 imageLength, lineSize, cols, rows;
  795.   guchar *buffer;
  796.   int i, y, tile_height = gimp_tile_height ();
  797.  
  798.   TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar);
  799.   TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
  800.   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &cols);
  801.   lineSize= TIFFScanlineSize(tif);
  802.  
  803.   for (i= 0; i <= extra; ++i) {
  804.     channel[i].pixels= g_new(guchar, tile_height * cols
  805.                                           * channel[i].drawable->bpp);
  806.   }
  807.  
  808.   buffer = g_malloc(lineSize * tile_height);
  809.   if (planar == PLANARCONFIG_CONTIG) {
  810.     for (y = 0; y < imageLength; y+= tile_height ) {
  811.       if (run_mode == GIMP_RUN_INTERACTIVE)
  812.         gimp_progress_update ( (double) y / (double) imageLength);
  813.       rows = MIN(tile_height, imageLength - y);
  814.       for (i = 0; i < rows; ++i)
  815.     TIFFReadScanline(tif, buffer + i * lineSize, y + i, 0);
  816.       if (bps == 16) {
  817.           g_message("WARNING: The GIMP does not support 16 bits per channel. Truncating data to 8 bits per channel.");
  818.     read_16bit(buffer, channel, photomet, y, 0, rows, cols,
  819.                    alpha, extra, 0);
  820.       } else if (bps == 8) {
  821.     read_8bit(buffer, channel, photomet, y, 0, rows, cols,
  822.                   alpha, extra, 0);
  823.       } else {
  824.     read_default(buffer, channel, bps, photomet, y, 0, rows, cols,
  825.                      alpha, extra, 0);
  826.       }
  827.     }
  828.   } else { /* PLANARCONFIG_SEPARATE  -- Just say "No" */
  829.     uint16 s, samples;
  830.     TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samples);
  831.     for (s = 0; s < samples; ++s) {
  832.       for (y = 0; y < imageLength; y+= tile_height ) {
  833.         if (run_mode == GIMP_RUN_INTERACTIVE)
  834.       gimp_progress_update ( (double) y / (double) imageLength);
  835.     rows = MIN(tile_height, imageLength - y);
  836.     for (i = 0; i < rows; ++i)
  837.       TIFFReadScanline(tif, buffer + i * lineSize, y + i, s);
  838.     read_separate (buffer, channel, bps, photomet,
  839.                  y, 0, rows, cols, alpha, extra, s);
  840.       }
  841.     }
  842.   }
  843.   for (i= 0; i <= extra; ++i) {
  844.     g_free(channel[i].pixels);
  845.   }
  846.   g_free(buffer);
  847. }
  848.  
  849. static void
  850. read_16bit (guchar       *source,
  851.         channel_data *channel,
  852.         gushort       photomet,
  853.         gint          startrow,
  854.         gint          startcol,
  855.         gint          rows,
  856.         gint          cols,
  857.         gint          alpha,
  858.             gint          extra,
  859.             gint          align)
  860. {
  861.   guchar *dest;
  862.   gint    gray_val, red_val, green_val, blue_val, alpha_val;
  863.   gint    col, row, i;
  864.  
  865.   for (i= 0; i <= extra; ++i) {
  866.     gimp_pixel_rgn_init (&(channel[i].pixel_rgn), channel[i].drawable,
  867.                           startcol, startrow, cols, rows, TRUE, FALSE);
  868.   }
  869.  
  870. #if G_BYTE_ORDER == G_LITTLE_ENDIAN
  871.   source++; /* offset source once, to look at the high byte */
  872. #endif
  873.  
  874.   for (row = 0; row < rows; ++row) {
  875.     dest= channel[0].pixels + row * cols * channel[0].drawable->bpp;
  876.  
  877.     for (i= 1; i <= extra; ++i) {
  878.       channel[i].pixel= channel[i].pixels + row * cols;
  879.     }
  880.  
  881.     for (col = 0; col < cols; col++) {
  882.       switch (photomet) {
  883.         case PHOTOMETRIC_MINISBLACK:
  884.           if (alpha) {
  885.             gray_val= *source; source+= 2;
  886.             alpha_val= *source; source+= 2;
  887.             gray_val= MIN(gray_val, alpha_val);
  888.             if (alpha_val)
  889.               *dest++ = gray_val * 255 / alpha_val;
  890.             else
  891.               *dest++ = 0;
  892.             *dest++ = alpha_val;
  893.           } else {
  894.             *dest++ = *source; source+= 2;
  895.           }
  896.           break;
  897.  
  898.         case PHOTOMETRIC_MINISWHITE:
  899.           if (alpha) {
  900.             gray_val= *source; source+= 2;
  901.             alpha_val= *source; source+= 2;
  902.             gray_val= MIN(gray_val, alpha_val);
  903.             if (alpha_val)
  904.               *dest++ = ((alpha_val - gray_val) * 255) / alpha_val;
  905.             else
  906.               *dest++ = 0;
  907.             *dest++ = alpha_val;
  908.           } else {
  909.             *dest++ = ~(*source); source+= 2;
  910.           }
  911.           break;
  912.  
  913.         case PHOTOMETRIC_PALETTE:
  914.           *dest++= *source; source+= 2;
  915.           if (alpha) *dest++= *source; source+= 2;
  916.           break;
  917.   
  918.         case PHOTOMETRIC_RGB:
  919.           if (alpha) {
  920.             red_val= *source; source+= 2;
  921.             green_val= *source; source+= 2;
  922.             blue_val= *source; source+= 2;
  923.             alpha_val= *source; source+= 2;
  924.             red_val= MIN(red_val, alpha_val);
  925.             green_val= MIN(green_val, alpha_val);
  926.             blue_val= MIN(blue_val, alpha_val);
  927.             if (alpha_val) {
  928.               *dest++ = (red_val * 255) / alpha_val;
  929.               *dest++ = (green_val * 255) / alpha_val;
  930.               *dest++ = (blue_val * 255) / alpha_val;
  931.             } else {
  932.               *dest++ = 0;
  933.               *dest++ = 0;
  934.               *dest++ = 0;
  935.         }
  936.         *dest++ = alpha_val;
  937.       } else {
  938.         *dest++ = *source; source+= 2;
  939.         *dest++ = *source; source+= 2;
  940.         *dest++ = *source; source+= 2;
  941.       }
  942.           break;
  943.  
  944.         default:
  945.           /* This case was handled earlier */
  946.           g_assert_not_reached();
  947.       }
  948.       for (i= 1; i <= extra; ++i) {
  949.         *channel[i].pixel++ = *source; source+= 2;
  950.       }
  951.     }
  952.     if (align) {
  953.       switch (photomet) {
  954.         case PHOTOMETRIC_MINISBLACK:
  955.         case PHOTOMETRIC_MINISWHITE:
  956.         case PHOTOMETRIC_PALETTE:
  957.           source+= align * (1 + alpha + extra) * 2;
  958.           break;
  959.         case PHOTOMETRIC_RGB:
  960.           source+= align * (3 + alpha + extra) * 2;
  961.           break;
  962.       }
  963.     }
  964.   }
  965.   for (i= 0; i <= extra; ++i) {
  966.     gimp_pixel_rgn_set_rect(&(channel[i].pixel_rgn), channel[i].pixels,
  967.                               startcol, startrow, cols, rows);
  968.   }
  969. }
  970.  
  971. static void
  972. read_8bit (guchar       *source,
  973.        channel_data *channel,
  974.        gushort       photomet,
  975.        gint          startrow,
  976.        gint          startcol,
  977.        gint          rows,
  978.        gint          cols,
  979.        gint          alpha,
  980.        gint          extra,
  981.        gint          align)
  982. {
  983.   guchar *dest;
  984.   gint    gray_val, red_val, green_val, blue_val, alpha_val;
  985.   gint    col, row, i;
  986.  
  987.   for (i= 0; i <= extra; ++i) {
  988.     gimp_pixel_rgn_init (&(channel[i].pixel_rgn), channel[i].drawable,
  989.                           startcol, startrow, cols, rows, TRUE, FALSE);
  990.   }
  991.  
  992.   for (row = 0; row < rows; ++row) {
  993.     dest= channel[0].pixels + row * cols * channel[0].drawable->bpp;
  994.  
  995.     for (i= 1; i <= extra; ++i) {
  996.       channel[i].pixel= channel[i].pixels + row * cols;
  997.     }
  998.  
  999.     for (col = 0; col < cols; col++) {
  1000.       switch (photomet) {
  1001.         case PHOTOMETRIC_MINISBLACK:
  1002.           if (alpha) {
  1003.             gray_val= *source++;
  1004.             alpha_val= *source++;
  1005.             gray_val= MIN(gray_val, alpha_val);
  1006.             if (alpha_val)
  1007.               *dest++ = gray_val * 255 / alpha_val;
  1008.             else
  1009.               *dest++ = 0;
  1010.             *dest++ = alpha_val;
  1011.           } else {
  1012.             *dest++ = *source++;
  1013.           }
  1014.           break;
  1015.  
  1016.         case PHOTOMETRIC_MINISWHITE:
  1017.           if (alpha) {
  1018.             gray_val= *source++;
  1019.             alpha_val= *source++;
  1020.             gray_val= MIN(gray_val, alpha_val);
  1021.             if (alpha_val)
  1022.               *dest++ = ((alpha_val - gray_val) * 255) / alpha_val;
  1023.             else
  1024.               *dest++ = 0;
  1025.             *dest++ = alpha_val;
  1026.           } else {
  1027.             *dest++ = ~(*source++);
  1028.           }
  1029.           break;
  1030.  
  1031.         case PHOTOMETRIC_PALETTE:
  1032.           *dest++= *source++;
  1033.           if (alpha) *dest++= *source++;
  1034.           break;
  1035.   
  1036.         case PHOTOMETRIC_RGB:
  1037.           if (alpha) {
  1038.             red_val= *source++;
  1039.             green_val= *source++;
  1040.             blue_val= *source++;
  1041.             alpha_val= *source++;
  1042.             red_val= MIN(red_val, alpha_val);
  1043.             blue_val= MIN(blue_val, alpha_val);
  1044.             green_val= MIN(green_val, alpha_val);
  1045.             if (alpha_val) {
  1046.               *dest++ = (red_val * 255) / alpha_val;
  1047.               *dest++ = (green_val * 255) / alpha_val;
  1048.               *dest++ = (blue_val * 255) / alpha_val;
  1049.             } else {
  1050.               *dest++ = 0;
  1051.               *dest++ = 0;
  1052.               *dest++ = 0;
  1053.         }
  1054.         *dest++ = alpha_val;
  1055.       } else {
  1056.         *dest++ = *source++;
  1057.         *dest++ = *source++;
  1058.         *dest++ = *source++;
  1059.       }
  1060.           break;
  1061.  
  1062.         default:
  1063.           /* This case was handled earlier */
  1064.           g_assert_not_reached();
  1065.       }
  1066.       for (i= 1; i <= extra; ++i) {
  1067.         *channel[i].pixel++ = *source++;
  1068.       }
  1069.     }
  1070.     if (align) {
  1071.       switch (photomet) {
  1072.         case PHOTOMETRIC_MINISBLACK:
  1073.         case PHOTOMETRIC_MINISWHITE:
  1074.         case PHOTOMETRIC_PALETTE:
  1075.           source+= align * (1 + alpha + extra);
  1076.           break;
  1077.         case PHOTOMETRIC_RGB:
  1078.           source+= align * (3 + alpha + extra);
  1079.           break;
  1080.       }
  1081.     }
  1082.   }
  1083.   for (i= 0; i <= extra; ++i) {
  1084.     gimp_pixel_rgn_set_rect(&(channel[i].pixel_rgn), channel[i].pixels,
  1085.                               startcol, startrow, cols, rows);
  1086.   }
  1087. }
  1088.  
  1089. /* Step through all <= 8-bit samples in an image */
  1090.  
  1091. #define NEXTSAMPLE(var)                       \
  1092.   {                                           \
  1093.       if (bitsleft == 0)                      \
  1094.       {                                       \
  1095.       source++;                           \
  1096.       bitsleft = 8;                       \
  1097.       }                                       \
  1098.       bitsleft -= bps;                        \
  1099.       var = ( *source >> bitsleft ) & maxval; \
  1100.   }
  1101.  
  1102. static void
  1103. read_default (guchar       *source,
  1104.           channel_data *channel,
  1105.           gushort       bps,
  1106.           gushort       photomet,
  1107.           gint          startrow,
  1108.           gint          startcol,
  1109.           gint          rows,
  1110.           gint          cols,
  1111.           gint          alpha,
  1112.           gint          extra,
  1113.               gint          align)
  1114. {
  1115.   guchar *dest;
  1116.   gint    gray_val, red_val, green_val, blue_val, alpha_val;
  1117.   gint    col, row, i;
  1118.   gint    bitsleft = 8, maxval = (1 << bps) - 1;
  1119.  
  1120.   for (i= 0; i <= extra; ++i) {
  1121.     gimp_pixel_rgn_init (&(channel[i].pixel_rgn), channel[i].drawable,
  1122.         startcol, startrow, cols, rows, TRUE, FALSE);
  1123.   }
  1124.  
  1125.   for (row = 0; row < rows; ++row) {
  1126.     dest= channel[0].pixels + row * cols * channel[0].drawable->bpp;
  1127.  
  1128.     for (i= 1; i <= extra; ++i) {
  1129.       channel[i].pixel= channel[i].pixels + row * cols;
  1130.     }
  1131.  
  1132.     for (col = 0; col < cols; col++) {
  1133.       switch (photomet) {
  1134.         case PHOTOMETRIC_MINISBLACK:
  1135.           NEXTSAMPLE(gray_val);
  1136.           if (alpha) {
  1137.             NEXTSAMPLE(alpha_val);
  1138.             gray_val= MIN(gray_val, alpha_val);
  1139.             if (alpha_val)
  1140.               *dest++ = (gray_val * 65025) / (alpha_val * maxval);
  1141.             else
  1142.               *dest++ = 0;
  1143.             *dest++ = alpha_val;
  1144.           } else {
  1145.             *dest++ = (gray_val * 255) / maxval;
  1146.           }
  1147.           break;
  1148.  
  1149.         case PHOTOMETRIC_MINISWHITE:
  1150.           NEXTSAMPLE(gray_val);
  1151.           if (alpha) {
  1152.             NEXTSAMPLE(alpha_val);
  1153.             gray_val= MIN(gray_val, alpha_val);
  1154.             if (alpha_val)
  1155.               *dest++ = ((maxval - gray_val) * 65025) / (alpha_val * maxval);
  1156.             else
  1157.               *dest++ = 0;
  1158.             *dest++ = alpha_val;
  1159.           } else {
  1160.             *dest++ = ((maxval - gray_val) * 255) / maxval;
  1161.           }
  1162.           break;
  1163.  
  1164.         case PHOTOMETRIC_PALETTE:
  1165.           NEXTSAMPLE(*dest++);
  1166.           if (alpha) {
  1167.             NEXTSAMPLE(*dest++);
  1168.           }
  1169.           break;
  1170.   
  1171.         case PHOTOMETRIC_RGB:
  1172.           NEXTSAMPLE(red_val)
  1173.           NEXTSAMPLE(green_val)
  1174.           NEXTSAMPLE(blue_val)
  1175.           if (alpha) {
  1176.             NEXTSAMPLE(alpha_val)
  1177.             red_val= MIN(red_val, alpha_val);
  1178.             blue_val= MIN(blue_val, alpha_val);
  1179.             green_val= MIN(green_val, alpha_val);
  1180.             if (alpha_val) {
  1181.               *dest++ = (red_val * 255) / alpha_val;
  1182.               *dest++ = (green_val * 255) / alpha_val;
  1183.               *dest++ = (blue_val * 255) / alpha_val;
  1184.             } else {
  1185.               *dest++ = 0;
  1186.               *dest++ = 0;
  1187.               *dest++ = 0;
  1188.         }
  1189.         *dest++ = alpha_val;
  1190.       } else {
  1191.         *dest++ = red_val;
  1192.         *dest++ = green_val;
  1193.         *dest++ = blue_val;
  1194.       }
  1195.           break;
  1196.  
  1197.         default:
  1198.           /* This case was handled earlier */
  1199.           g_assert_not_reached();
  1200.       }
  1201.       for (i= 1; i <= extra; ++i) {
  1202.         NEXTSAMPLE(alpha_val);
  1203.         *channel[i].pixel++ = alpha_val;
  1204.       }
  1205.     }
  1206.     if (align) {
  1207.       switch (photomet) {
  1208.         case PHOTOMETRIC_MINISBLACK:
  1209.         case PHOTOMETRIC_MINISWHITE:
  1210.         case PHOTOMETRIC_PALETTE:
  1211.           for (i= 0; i < align * (1 + alpha + extra); ++i) {
  1212.             NEXTSAMPLE(alpha_val);
  1213.           }
  1214.           break;
  1215.         case PHOTOMETRIC_RGB:
  1216.           for (i= 0; i < align * (3 + alpha + extra); ++i) {
  1217.             NEXTSAMPLE(alpha_val);
  1218.           }
  1219.           break;
  1220.       }
  1221.     }
  1222.     bitsleft= 0;
  1223.   }
  1224.   for (i= 0; i <= extra; ++i) {
  1225.     gimp_pixel_rgn_set_rect(&(channel[i].pixel_rgn), channel[i].pixels,
  1226.                               startcol, startrow, cols, rows);
  1227.   }
  1228. }
  1229.  
  1230. static void
  1231. read_separate (guchar       *source,
  1232.            channel_data *channel,
  1233.                gushort       bps,
  1234.            gushort       photomet,
  1235.                gint          startrow,
  1236.            gint          startcol,
  1237.            gint          rows,
  1238.            gint          cols,
  1239.                gint          alpha,
  1240.            gint          extra,
  1241.            gint          sample)
  1242. {
  1243.   guchar *dest;
  1244.   gint    col, row, c;
  1245.   gint    bitsleft = 8, maxval = (1 << bps) - 1;
  1246.  
  1247.   if (bps > 8) {
  1248.     g_message("TIFF Unsupported layout\n");
  1249.     gimp_quit();
  1250.   }
  1251.  
  1252.   if (sample < channel[0].drawable->bpp) {
  1253.     c = 0;
  1254.   } else {
  1255.     c = (sample - channel[0].drawable->bpp) + 4;
  1256.     photomet = PHOTOMETRIC_MINISBLACK;
  1257.   }
  1258.  
  1259.   gimp_pixel_rgn_init (&(channel[c].pixel_rgn), channel[c].drawable,
  1260.                          startcol, startrow, cols, rows, TRUE, FALSE);
  1261.  
  1262.   gimp_pixel_rgn_get_rect(&(channel[c].pixel_rgn), channel[c].pixels,
  1263.                             startcol, startrow, cols, rows);
  1264.   for (row = 0; row < rows; ++row) {
  1265.     dest = channel[c].pixels + row * cols * channel[c].drawable->bpp;
  1266.     if (c == 0) {
  1267.       for (col = 0; col < cols; ++col) {
  1268.         NEXTSAMPLE(dest[col * channel[0].drawable->bpp + sample]);
  1269.       }
  1270.     } else {
  1271.       for (col = 0; col < cols; ++col)
  1272.         NEXTSAMPLE(dest[col]);
  1273.     }
  1274.   }
  1275.   gimp_pixel_rgn_set_rect(&(channel[c].pixel_rgn), channel[c].pixels,
  1276.                             startcol, startrow, cols, rows);
  1277. }
  1278.  
  1279. /*
  1280. ** pnmtotiff.c - converts a portable anymap to a Tagged Image File
  1281. **
  1282. ** Derived by Jef Poskanzer from ras2tif.c, which is:
  1283. **
  1284. ** Copyright (c) 1990 by Sun Microsystems, Inc.
  1285. **
  1286. ** Author: Patrick J. Naughton
  1287. ** naughton@wind.sun.com
  1288. **
  1289. ** This file is provided AS IS with no warranties of any kind.  The author
  1290. ** shall have no liability with respect to the infringement of copyrights,
  1291. ** trade secrets or any patents by this file or any part thereof.  In no
  1292. ** event will the author be liable for any lost revenue or profits or
  1293. ** other special, indirect and consequential damages.
  1294. */
  1295.  
  1296. static gint
  1297. save_image (gchar   *filename, 
  1298.         gint32   image, 
  1299.         gint32   layer,
  1300.         gint32   orig_image)  /* the export function might have created a duplicate */  
  1301. {
  1302.   TIFF          *tif;
  1303.   gushort        red[256];
  1304.   gushort        grn[256];
  1305.   gushort        blu[256];
  1306.   gint           cols, col, rows, row, i;
  1307.   glong          rowsperstrip;
  1308.   gushort        compression;
  1309.   gushort        extra_samples[1];
  1310.   gint           alpha;
  1311.   gshort         predictor;
  1312.   gshort         photometric;
  1313.   gshort         samplesperpixel;
  1314.   gshort         bitspersample;
  1315.   gint           bytesperrow;
  1316.   guchar        *t, *src, *data;
  1317.   guchar        *cmap;
  1318.   gint           colors;
  1319.   gint           success;
  1320.   GimpDrawable     *drawable;
  1321.   GimpImageType  drawable_type;
  1322.   GimpPixelRgn      pixel_rgn;
  1323.   gint           tile_height;
  1324.   gint           y, yend;
  1325.   gchar         *name;
  1326.  
  1327.   compression = tsvals.compression;
  1328.  
  1329.   /* Disabled because this isn't in older releases of libtiff, and it
  1330.      wasn't helping much anyway */
  1331. #if 0
  1332.   if (TIFFFindCODEC((uint16) compression) == NULL)
  1333.     compression = COMPRESSION_NONE; /* CODEC not available */
  1334. #endif
  1335.  
  1336.   predictor = 0;
  1337.   tile_height = gimp_tile_height ();
  1338.   rowsperstrip = tile_height;
  1339.  
  1340.   TIFFSetWarningHandler (tiff_warning);
  1341.   TIFFSetErrorHandler (tiff_error);
  1342.  
  1343.   tif = TIFFOpen (filename, "w");
  1344.   if (!tif) 
  1345.     {
  1346.       g_print ("Can't write image to\n%s", filename);
  1347.       return 0;
  1348.     }
  1349.  
  1350.   if (run_mode == GIMP_RUN_INTERACTIVE) {
  1351.     name = g_strdup_printf( _("Saving %s:"), filename);
  1352.     gimp_progress_init (name);
  1353.     g_free (name);
  1354.   }
  1355.  
  1356.   drawable = gimp_drawable_get (layer);
  1357.   drawable_type = gimp_drawable_type (layer);
  1358.   gimp_pixel_rgn_init (&pixel_rgn, drawable,
  1359.                0, 0, drawable->width, drawable->height, FALSE, FALSE);
  1360.  
  1361.   cols = drawable->width;
  1362.   rows = drawable->height;
  1363.  
  1364.   switch (drawable_type)
  1365.     {
  1366.     case GIMP_RGB_IMAGE:
  1367.       predictor = 2;
  1368.       samplesperpixel = 3;
  1369.       bitspersample = 8;
  1370.       photometric = PHOTOMETRIC_RGB;
  1371.       bytesperrow = cols * 3;
  1372.       alpha = 0;
  1373.       break;
  1374.     case GIMP_GRAY_IMAGE:
  1375.       samplesperpixel = 1;
  1376.       bitspersample = 8;
  1377.       photometric = PHOTOMETRIC_MINISBLACK;
  1378.       bytesperrow = cols;
  1379.       alpha = 0;
  1380.       break;
  1381.     case GIMP_RGBA_IMAGE:
  1382.       predictor = 2;
  1383.       samplesperpixel = 4;
  1384.       bitspersample = 8;
  1385.       photometric = PHOTOMETRIC_RGB;
  1386.       bytesperrow = cols * 4;
  1387.       alpha = 1;
  1388.       break;
  1389.     case GIMP_GRAYA_IMAGE:
  1390.       samplesperpixel = 2;
  1391.       bitspersample = 8;
  1392.       photometric = PHOTOMETRIC_MINISBLACK;
  1393.       bytesperrow = cols * 2;
  1394.       alpha = 1;
  1395.       break;
  1396.     case GIMP_INDEXED_IMAGE:
  1397.       samplesperpixel = 1;
  1398.       bitspersample = 8;
  1399.       photometric = PHOTOMETRIC_PALETTE;
  1400.       bytesperrow = cols;
  1401.       alpha = 0;
  1402.  
  1403.       cmap = gimp_image_get_cmap (image, &colors);
  1404.  
  1405.       for (i = 0; i < colors; i++)
  1406.     {
  1407.       red[i] = *cmap++ * 65535 / 255;
  1408.       grn[i] = *cmap++ * 65535 / 255;
  1409.       blu[i] = *cmap++ * 65535 / 255;
  1410.     }
  1411.       break;
  1412.     case GIMP_INDEXEDA_IMAGE:
  1413.       return 0;
  1414.      default:
  1415.       return 0;
  1416.     }
  1417.  
  1418.   /* Set TIFF parameters. */
  1419.   TIFFSetField (tif, TIFFTAG_SUBFILETYPE, 0);
  1420.   TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, cols);
  1421.   TIFFSetField (tif, TIFFTAG_IMAGELENGTH, rows);
  1422.   TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
  1423.   TIFFSetField (tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
  1424.   TIFFSetField (tif, TIFFTAG_COMPRESSION, compression);
  1425.   if ((compression == COMPRESSION_LZW || compression == COMPRESSION_DEFLATE)
  1426.      && (predictor != 0)) {
  1427.     TIFFSetField (tif, TIFFTAG_PREDICTOR, predictor);
  1428.   }
  1429.   if (alpha) {
  1430.       extra_samples [0] = EXTRASAMPLE_ASSOCALPHA;
  1431.       TIFFSetField (tif, TIFFTAG_EXTRASAMPLES, 1, extra_samples);
  1432.   }
  1433.   TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, photometric);
  1434.   TIFFSetField (tif, TIFFTAG_DOCUMENTNAME, filename);
  1435.   TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
  1436.   TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
  1437.   /* TIFFSetField( tif, TIFFTAG_STRIPBYTECOUNTS, rows / rowsperstrip ); */
  1438.   TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  1439.  
  1440. #ifdef GIMP_HAVE_RESOLUTION_INFO
  1441.   /* resolution fields */
  1442.   {
  1443.     gdouble  xresolution;
  1444.     gdouble  yresolution;
  1445.     gushort  save_unit = RESUNIT_INCH;
  1446.     GimpUnit unit;
  1447.     gfloat   factor;
  1448.  
  1449.     gimp_image_get_resolution (orig_image, &xresolution, &yresolution);
  1450.     unit = gimp_image_get_unit (orig_image);
  1451.     factor = gimp_unit_get_factor (unit);
  1452.  
  1453.     /*  if we have a metric unit, save the resolution as centimeters
  1454.      */
  1455.     if ((ABS (factor - 0.0254) < 1e-5) ||  /* m  */
  1456.     (ABS (factor - 0.254) < 1e-5) ||   /* dm */
  1457.     (ABS (factor - 2.54) < 1e-5) ||    /* cm */
  1458.     (ABS (factor - 25.4) < 1e-5))      /* mm */
  1459.       {
  1460.     save_unit = RESUNIT_CENTIMETER;
  1461.     xresolution /= 2.54;
  1462.     yresolution /= 2.54;
  1463.       }
  1464.  
  1465.     if (xresolution > 1e-5 && yresolution > 1e-5)
  1466.       {
  1467.     TIFFSetField (tif, TIFFTAG_XRESOLUTION, xresolution);
  1468.     TIFFSetField (tif, TIFFTAG_YRESOLUTION, yresolution);
  1469.     TIFFSetField (tif, TIFFTAG_RESOLUTIONUNIT, save_unit);
  1470.       }
  1471.   }
  1472. #endif /* GIMP_HAVE_RESOLUTION_INFO */
  1473.  
  1474.   /* do we have a comment?  If so, create a new parasite to hold it,
  1475.    * and attach it to the image. The attach function automatically
  1476.    * detaches a previous incarnation of the parasite. */
  1477. #ifdef GIMP_HAVE_PARASITES
  1478.   if (image_comment && *image_comment != '\000')
  1479.     {
  1480.       GimpParasite *parasite;
  1481.       
  1482.       TIFFSetField (tif, TIFFTAG_IMAGEDESCRIPTION, image_comment);
  1483.       parasite = gimp_parasite_new ("gimp-comment",
  1484.                     GIMP_PARASITE_PERSISTENT,
  1485.                     strlen (image_comment) + 1, image_comment);
  1486.       gimp_image_parasite_attach (orig_image, parasite);
  1487.       gimp_parasite_free (parasite);
  1488.     }
  1489. #endif /* GIMP_HAVE_PARASITES */
  1490.  
  1491.   /* do we have an ICC profile? If so, write it to the TIFF file */
  1492. #ifdef GIMP_HAVE_PARASITES
  1493. #ifdef TIFFTAG_ICCPROFILE
  1494.   {
  1495.     GimpParasite *parasite;
  1496.     uint32 profile_size;
  1497.     guchar *icc_profile;
  1498.  
  1499.     parasite = gimp_image_parasite_find (orig_image, "icc-profile");
  1500.     if (parasite)
  1501.       {
  1502.         profile_size = gimp_parasite_data_size(parasite);
  1503.     icc_profile = gimp_parasite_data(parasite);
  1504.  
  1505.     TIFFSetField(tif, TIFFTAG_ICCPROFILE, profile_size, icc_profile);
  1506.         gimp_parasite_free(parasite);
  1507.       }
  1508.   }
  1509. #endif
  1510. #endif
  1511.  
  1512.   if (drawable_type == GIMP_INDEXED_IMAGE)
  1513.     TIFFSetField (tif, TIFFTAG_COLORMAP, red, grn, blu);
  1514.  
  1515.   /* array to rearrange data */
  1516.   src = g_new (guchar, bytesperrow * tile_height);
  1517.   data = g_new (guchar, bytesperrow);
  1518.  
  1519.   /* Now write the TIFF data. */
  1520.   for (y = 0; y < rows; y = yend)
  1521.     {
  1522.       yend = y + tile_height;
  1523.       yend = MIN (yend, rows);
  1524.  
  1525.       gimp_pixel_rgn_get_rect (&pixel_rgn, src, 0, y, cols, yend - y);
  1526.  
  1527.       for (row = y; row < yend; row++)
  1528.     {
  1529.       t = src + bytesperrow * (row - y);
  1530.  
  1531.       switch (drawable_type)
  1532.         {
  1533.         case GIMP_INDEXED_IMAGE:
  1534.           success = (TIFFWriteScanline (tif, t, row, 0) >= 0);
  1535.           break;
  1536.         case GIMP_GRAY_IMAGE:
  1537.           success = (TIFFWriteScanline (tif, t, row, 0) >= 0);
  1538.           break;
  1539.         case GIMP_GRAYA_IMAGE:
  1540.           for (col = 0; col < cols*samplesperpixel; col+=samplesperpixel)
  1541.         {
  1542.           /* pre-multiply gray by alpha */
  1543.           data[col + 0] = (t[col + 0] * t[col + 1]) / 255;
  1544.           data[col + 1] = t[col + 1];  /* alpha channel */
  1545.         }
  1546.           success = (TIFFWriteScanline (tif, data, row, 0) >= 0);
  1547.           break;
  1548.         case GIMP_RGB_IMAGE:
  1549.           success = (TIFFWriteScanline (tif, t, row, 0) >= 0);
  1550.           break;
  1551.         case GIMP_RGBA_IMAGE:
  1552.           for (col = 0; col < cols*samplesperpixel; col+=samplesperpixel)
  1553.         {
  1554.           /* pre-multiply rgb by alpha */
  1555.           data[col+0] = t[col + 0] * t[col + 3] / 255;
  1556.           data[col+1] = t[col + 1] * t[col + 3] / 255;
  1557.           data[col+2] = t[col + 2] * t[col + 3] / 255;
  1558.           data[col+3] = t[col + 3];  /* alpha channel */
  1559.         }
  1560.           success = (TIFFWriteScanline (tif, data, row, 0) >= 0);
  1561.           break;
  1562.         default:
  1563.           success = FALSE;
  1564.           break;
  1565.         }
  1566.  
  1567.       if (!success) {
  1568.         g_message ("TIFF Failed a scanline write on row %d", row);
  1569.         return 0;
  1570.       }
  1571.     }
  1572.  
  1573.       if (run_mode == GIMP_RUN_INTERACTIVE)
  1574.         gimp_progress_update ((double) row / (double) rows);
  1575.     }
  1576.  
  1577.   TIFFFlushData (tif);
  1578.   TIFFClose (tif);
  1579.  
  1580.   gimp_drawable_detach (drawable);
  1581.   g_free (data);
  1582.  
  1583.   return 1;
  1584. }
  1585.  
  1586. static gint
  1587. save_dialog (void)
  1588. {
  1589.   GtkWidget *dlg;
  1590.   GtkWidget *vbox;
  1591.   GtkWidget *frame;
  1592.   GtkWidget *hbox;
  1593.   GtkWidget *label;
  1594.   GtkWidget *entry;
  1595.  
  1596.   dlg = gimp_dialog_new ( _("Save as TIFF"), "tiff",
  1597.              gimp_standard_help_func, "filters/tiff.html",
  1598.              GTK_WIN_POS_MOUSE,
  1599.              FALSE, TRUE, FALSE,
  1600.  
  1601.              _("OK"), save_ok_callback,
  1602.              NULL, NULL, NULL, TRUE, FALSE,
  1603.              _("Cancel"), gtk_widget_destroy,
  1604.              NULL, 1, NULL, FALSE, TRUE,
  1605.  
  1606.              NULL);
  1607.  
  1608.   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
  1609.               GTK_SIGNAL_FUNC (gtk_main_quit),
  1610.               NULL);
  1611.  
  1612.   vbox = gtk_vbox_new (FALSE, 4);
  1613.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
  1614.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), vbox, FALSE, TRUE, 0);
  1615.  
  1616.   /*  compression  */
  1617.   frame =
  1618.     gimp_radio_group_new2 (TRUE, _("Compression"),
  1619.                gimp_radio_button_update,
  1620.                &tsvals.compression, GINT_TO_POINTER (tsvals.compression),
  1621.  
  1622.                _("None"),      GINT_TO_POINTER (COMPRESSION_NONE), NULL,
  1623.                _("LZW"),       GINT_TO_POINTER (COMPRESSION_LZW), NULL,
  1624.                _("Pack Bits"), GINT_TO_POINTER (COMPRESSION_PACKBITS), NULL,
  1625.                _("Deflate"),   GINT_TO_POINTER (COMPRESSION_DEFLATE), NULL,
  1626.                _("JPEG"),      GINT_TO_POINTER (COMPRESSION_JPEG), NULL,
  1627.  
  1628.                NULL);
  1629.   gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
  1630.   gtk_widget_show (frame);
  1631.  
  1632.   /* comment entry */
  1633.   hbox = gtk_hbox_new (FALSE, 4);
  1634.   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  1635.   gtk_widget_show (hbox);
  1636.  
  1637.   label = gtk_label_new ( _("Comment:"));
  1638.   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  1639.   gtk_widget_show (label);
  1640.  
  1641.   entry = gtk_entry_new ();
  1642.   gtk_widget_show (entry);
  1643.   gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
  1644.   gtk_entry_set_text (GTK_ENTRY (entry), image_comment);
  1645.   gtk_signal_connect (GTK_OBJECT (entry), "changed",
  1646.                       GTK_SIGNAL_FUNC (comment_entry_callback),
  1647.                       NULL);
  1648.  
  1649.   gtk_widget_show (frame);
  1650.  
  1651.   gtk_widget_show (vbox);
  1652.   gtk_widget_show (dlg);
  1653.  
  1654.   gtk_main ();
  1655.   gdk_flush ();
  1656.  
  1657.   return tsint.run;
  1658. }
  1659.  
  1660. static void
  1661. save_ok_callback (GtkWidget *widget,
  1662.           gpointer   data)
  1663. {
  1664.   tsint.run = TRUE;
  1665.   gtk_widget_destroy (GTK_WIDGET (data));
  1666. }
  1667.  
  1668. static void
  1669. comment_entry_callback (GtkWidget *widget,
  1670.             gpointer   data)
  1671. {
  1672.   gint len;
  1673.   gchar *text;
  1674.  
  1675.   text = gtk_entry_get_text (GTK_ENTRY (widget));
  1676.   len = strlen (text);
  1677.  
  1678.   /* Temporary kludge for overlength strings - just return */
  1679.   if (len > 240)
  1680.     {
  1681.       g_message ("TIFF save: Your comment string is too long.\n");
  1682.       return;
  1683.     }
  1684.  
  1685.   g_free (image_comment);
  1686.   image_comment = g_strdup (text);
  1687.  
  1688.   /* g_print ("COMMENT: %s\n", image_comment); */
  1689. }
  1690.